package org.setamv.springcloud.hystrix.comprehesive;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheRemove;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
import org.setamv.springcloud.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * @DefaultProperties注解用于定义公共的Hystrix属性配置，每个方法可以覆盖该配置
 */
@Service
@DefaultProperties(groupKey = "testGroup", commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
})
public class GreetingsService {

    private int times = 0;

    /**
     * RestTemplate的Bean在 {@link org.setamv.springcloud.HystrixApplication} 中定义，增加了负载均衡
     */
    @Autowired
    private RestTemplate restTemplate;

    /**
     * CacheResult注解用于声明使用Hystrix缓存，generateCacheKey方法参见下面的 {@link #generateCacheKey(String)}
     * @param yourName
     * @return
     */
    @CacheResult(cacheKeyMethod = "generateCacheKey")
    @HystrixCommand(fallbackMethod = "greetingsFallback", commandKey = "testCommand", commandProperties = {})
    public String greetings(String yourName) {
        System.out.println("start greetings.");
        String url = times++ % 2 == 0 ? "http://service/greetings/from/" + yourName + "/slowly" : "http://service/greetings/from/" + yourName;
        String greetings = restTemplate.getForObject(url, String.class);
        return greetings;
    }

    /**
     * 这是一个获取Hystrix Cache Key的方法，该方法的入参必须与@CacheResult注解所在方法的入参一致，并且出参必须是String类型。
     * @param yourName
     * @return
     */
    public String generateCacheKey(String yourName) {
        return yourName;
    }

    /**
     * Hystrix的fallback方法
     * @param yourName
     * @return
     */
    public String greetingsFallback(String yourName) {
        return "fallback";
    }

    public String cacheKeyGenerator() {
        return "greetingsCacheKey";
    }

    /**
     * 删除缓存。
     * <p>
     * 注意：该方法的参数必须与方法 {@link #generateCacheKey(String)}的参数声明一致，每次删除的时候，只会删除之前 {@link #generateCacheKey(String)}使用参数 yourName缓存的值
     * 其次，该方法的{@link CacheRemove}注解中，commandKey也必须与声明了 {@link CacheResult}注解的方法中的 {@link HystrixCommand#commandKey()}一致
     */
    @CacheRemove(commandKey = "testCommand", cacheKeyMethod = "generateCacheKey")
    @HystrixCommand()
    public void removeCache(String yourName) {
        System.out.println("删除 " + yourName + " 对应的缓存。");
    }

}
